package net.gdface.utils;

import static net.gdface.utils.ConditionChecks.checkNotNull;
/**
 * 通过{@link VariableGetter}接口实例提供变量值,实现基于volatile的双重检查锁定实现懒加载变量实例<br>
 * 
 * @author guyadong
 *
 * @param <T> variable type
 * @see BaseVolatile
 * @since 2.6.6
 */
public class VolatileVariable<T> extends BaseVolatile<T>{
	private final VariableGetter<T> getter;
	/**
	 * 构造方法
	 * @param getter 提供变量值的实例
	 */
	public VolatileVariable(VariableGetter<T> getter) {
		this.getter = checkNotNull(getter,"getter is null");
	}
	@Override
	protected T doGet() {
		return getter.get();
	}
	public static interface VariableGetter<T>{
		public T get();
	}
	/**
	 * @param getter 提供变量值的实例
	 * @param reference 为{@code true}返回{@link ILazyInitVariable.VolatileReferenceVar}实例
	 * @since 2.9.9
	 */
	public static <T> ILazyInitVariable<T> create(final VariableGetter<T> getter,boolean reference){
		if(reference) {
			checkNotNull(getter,"getter is null");
			return new ILazyInitVariable.VolatileReferenceVar<T>() {
				@Override
				protected T doGet() {
					return getter.get();
				}};
		}else {
			return new VolatileVariable<>(getter);
		}
	}
	/**
	 * 返回{@link ILazyInitVariable.VolatileReferenceVar}实例
	 * @see #create(VariableGetter, boolean)
	 * @since 2.9.9
	 */
	public static <T> ILazyInitVariable<T> create(final VariableGetter<T> getter){
		return create(getter,true);
	}
}
